home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * DialogUtils.c - some useful odd bits to support dialogs
- *
- *
- * 19/7/94 ©1994, Graham Cox
- *
- *************************************************************************************************/
-
- #include "DialogUtils.h"
- #include "ThreeDEffects.h"
- #include "CursorUtilities.h"
- #include "DynamicLinking.h"
- #include "PrefManager.h"
- #include "MenuUtils.h"
- #include "CZoomChore.h"
- #include "CApplication.h"
- #include <fp.h>
- #include <string.h>
- #include <drag.h>
-
- #ifndef __COLOURLAB__
- #define __COLOURLAB__
- #endif
-
-
- typedef struct
- {
- short fieldID;
- short fieldType;
- }
- fieldInfo;
-
-
- typedef struct
- {
- DialogPtr theDlg;
- short itemID;
- short flags;
- }
- itemInfo;
-
-
- Rect gDialogZoomRect = {0,0,0,0};
-
- extern CApplication* gApplication;
-
-
- static Handle gFieldInfo = NULL;
- static itemInfo** gExtraDialogInfo = NULL;
-
- static short GetFieldType(short theField);
- static Boolean HasEditFields(DialogPtr theDialog);
-
- void OutlineDialogItem(DialogPtr theDialog,short theItem)
- {
- GrafPtr savePort;
- Handle itemHand;
- short itemType;
- Rect itemBox;
- PenState pnState;
-
- if (theDialog)
- {
- GetPort(&savePort);
- SetPort(theDialog);
- GetPenState(&pnState);
- PenNormal();
- PenMode(patCopy);
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if ((itemType & 0x7F) == (ctrlItem + btnCtrl))
- {
- if ((*(ControlHandle)itemHand)->contrlHilite == 255)
- {
- RGBColor grayRGB = {0x8888,0x8888,0x8888};
- RGBForeColor(&grayRGB);
- }
- InsetRect(&itemBox,-4,-4);
- PenSize(3,3);
- FrameRoundRect(&itemBox,16,16);
-
- ForeColor(blackColor);
- }
- SetPenState(&pnState);
- SetPort(savePort);
-
- }
- }
-
-
-
- pascal void FrameRectUserItem(DialogPtr theDialog,short theItem)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- Frame3DRect(&itemBox,kRecessedEmbossed);
- FrameRect(&itemBox);
- }
-
-
- pascal void FrameGrayRectUserItem(DialogPtr theDialog,short theItem)
- {
- // draws a 50% grey outline around the item's rect. This checks for the special case of
- // the item being less than 1 pixel wide or high, and if this is the case, draws a 3D
- // line instead. This is generally OK because the most common use for this proc is to
- // add decorative lines to dialog boxes.
-
- short itemType;
- Handle itemHand;
- Rect itemBox;
- PenState pnState;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- GetPenState(&pnState);
-
- if (((itemBox.right - itemBox.left) < 2) ||
- ((itemBox.bottom - itemBox.top) < 2))
- {
- MoveTo(itemBox.left,itemBox.top);
-
- // is this horizontal?
-
- if ((itemBox.right - itemBox.left) > (itemBox.bottom - itemBox.top))
- ThreeDLineTo(itemBox.right, itemBox.top, kRecessedEmbossed);
- else
- ThreeDLineTo(itemBox.left, itemBox.bottom, kRecessedEmbossed);
- }
- else
- {
- PenPat(&qd.gray);
- FrameRect(&itemBox);
- }
- SetPenState(&pnState);
- }
-
-
- pascal void EditFieldDecorator(DialogPtr theDialog,short theItem)
- {
- // this is a handy function for performing the 3D edit field enhancement without using
- // a special modal event filter. This is installed as a user item into any dummy user
- // item in the dialog. When it gets drawn, this routine is called which scans the item
- // list and decorates any edit fields it finds.
-
- Add3DDialogEffects(theDialog);
- }
-
-
- void SetUniversalUserItem(DialogPtr theDialog,short theItem,ProcPtr theProc)
- {
- // utility function to set up a user item procedure. This creates a routine descriptor
- // so it works on the PowerPC. However, this also means that the routine descriptor has to
- // be disposed of, so you must call DisposeUserItem as part of your clean up
-
- UserItemUPP uiProc;
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if ((itemType & 0x7F) == userItem)
- {
- uiProc = NewUserItemProc(theProc);
- itemHand = (Handle) uiProc;
- SetDItem(theDialog,theItem,itemType,itemHand,&itemBox);
- }
- }
-
-
- void DisposeUserItem(DialogPtr theDialog,short theItem)
- {
- // call if you allocated a routine descriptor for a user item
-
- UserItemUPP uiProc;
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if ((itemType & 0x7F) == userItem)
- {
- uiProc = (UserItemUPP) itemHand;
- DisposeRoutineDescriptor(uiProc);
- }
- }
-
- #ifndef __COLOURLAB__
-
- void DummyDialog(short dialogID)
- {
- // this is a handy function for creating user interface mockup apps. It displays any dialog
- // and handles it in a generic way. It is dismissed by an OK or Cancel button- other buttons
- // have no effect but checkboxes will toggle. It will also frame all user items found
-
- DialogPtr theDialog;
- short theItem,itemType,index,dCount;
- Handle itemHand;
- Rect itemBox;
- UserItemUPP uiProc;
- Boolean found1Edit = FALSE;
- ModalFilterUPP stdDialogProc;
-
- theDialog = GetNewDialog(dialogID,NULL,(WindowPtr) -1L);
-
- if (theDialog)
- {
- uiProc = NewUserItemProc((ProcPtr) FrameRectUserItem);
-
- // walk the DITL, getting user items and setting them to the framerect user item
-
- dCount = CountDITL(theDialog);
- for (index = 1;index <= dCount;index++)
- {
- GetDItem(theDialog,index,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == userItem)
- {
- itemHand = (Handle) uiProc;
- SetDItem(theDialog,index,itemType,itemHand,&itemBox);
- }
- if ((itemType & 0x7F) == editText && !found1Edit)
- {
- SelIText(theDialog,index,0,32767);
- found1Edit = TRUE;
- }
- }
- StdDialogSetup(theDialog);
- stdDialogProc = NewModalFilterProc((ProcPtr) StdMoveableFilterProc);
- RestoreDialogLocation(theDialog,dialogID);
- PutUpDialog(theDialog);
- OutlineDialogItem(theDialog,ok);
- theItem = 0;
-
- while (theItem == 0)
- {
- ModalDialog(stdDialogProc,&theItem);
-
- switch(theItem)
- {
- case ok:
- case cancel:
- break;
- default:
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if ((itemType & 0x7F) == ctrlItem + chkCtrl)
- SetCtlValue((ControlHandle) itemHand,GetCtlValue((ControlHandle) itemHand) ^ 1);
- theItem = 0;
- break;
- }
- }
- DisposeRoutineDescriptor(uiProc);
- DisposeRoutineDescriptor(stdDialogProc);
- SaveDialogLocation(theDialog,dialogID);
- TakeDownDialog(theDialog);
- DisposeDialog(theDialog);
- }
- }
-
- #endif
-
- void DrawDialogItem(DialogPtr theDialog,short theItem)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
- RgnHandle temp;
- GrafPtr savePort;
-
- if (theDialog)
- {
- GetPort(&savePort);
- SetPort(theDialog);
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if (EmptyRect(&itemBox))
- InsetRect(&itemBox,-1,-1);
- RectRgn(temp = NewRgn(),&itemBox);
- UpdtDialog(theDialog,temp);
- DisposeRgn(temp);
-
- SetPort(savePort);
- }
- }
-
- #ifndef __COLOURLAB__
-
- pascal Boolean StdMoveableFilterProc(DialogPtr theDialog,EventRecord *theEvent,short *item)
- {
- // allows ModalDialog calls to be used for Moveable Modals by passing other events to
- // the main loop for handling.
-
- Boolean returnValue = FALSE;
- GrafPtr savePort;
- ModalFilterUPP stdDialogProc;
- OSErr theErr;
- WindowPtr target;
- short partCode;
-
- switch (theEvent->what)
- {
- case activateEvt:
- if ((WindowPtr)theEvent->message == theDialog)
- {
- GetPort(&savePort);
- SetPort(theDialog);
-
- theErr = GetStdFilterProc(&stdDialogProc);
-
- if (theErr == noErr)
- returnValue = CallModalFilterProc(stdDialogProc,theDialog,theEvent,item);
- SetPort(savePort);
- }
- else
- {
- HandleOneEvent(theEvent);
- returnValue = TRUE;
- }
- break;
- case updateEvt:
- if ((WindowPtr)theEvent->message == theDialog)
- {
- Add3DDialogEffects(theDialog);
- OutlineDialogItem(theDialog,ok);
- returnValue = FALSE;
- }
- else
- {
- HandleOneEvent(theEvent);
- returnValue = TRUE;
- }
- break;
- case mouseDown:
- partCode = FindWindow(theEvent->where,&target);
- if ((partCode == inDrag) && (target == theDialog))
- {
- HandleOneEvent(theEvent);
- returnValue = TRUE;
- break;
- }
- // fall through to default case if we clicked elsewhere
- default:
- GetPort(&savePort);
- SetPort(theDialog);
-
- theErr = GetStdFilterProc(&stdDialogProc);
-
- if (theErr == noErr)
- {
- returnValue = CallModalFilterProc(stdDialogProc,theDialog,theEvent,item);
- //DisposeRoutineDescriptor(stdDialogProc);
- }
- SetPort(savePort);
- break;
- }
- if (gCursorTask)
- {
- StopCursorAnimation();
- InitCursor();
- }
- return(returnValue);
- }
-
- #endif
-
- void StdDialogSetup(DialogPtr theDialog)
- {
- // installs standard info for dialog handling- i.e. default ok and cancel buttons, etc
- // WARNING- make sure you only call this if you have both OK and cancel buttons or bomb!!!
-
- OSErr theErr;
-
- theErr = SetDialogDefaultItem(theDialog,ok);
- theErr = SetDialogCancelItem(theDialog,cancel);
- theErr = SetDialogTracksCursor(theDialog,TRUE);
- }
-
- #ifndef __COLOURLAB__
- void SaveDialogLocation(DialogPtr theDialog,short resID)
- {
- // saves the dialog location in the prefs file with the iD passed added to the location base
- // this is to avoid confusion with the window location resources, which are very similar.
-
- SaveWindowLocation(theDialog,resID + kDialogLocationIDBase,TRUE,FALSE);
- }
-
-
- void RestoreDialogLocation(DialogPtr theDialog,short resID)
- {
- // restores the dialog to its saved location
-
- (void) RestoreWindowLocation(theDialog,resID + kDialogLocationIDBase,TRUE);
- }
- #else
-
- #include "CWindowSaver.h"
-
- void SaveDialogLocation(DialogPtr theDialog,short resID)
- {
- // saves the dialog location in the prefs file with the iD passed added to the location base
- // this is to avoid confusion with the window location resources, which are very similar.
-
- if (gWindowSaver)
- gWindowSaver->SaveWindow(theDialog,resID + kDialogLocationIDBase);
- }
-
-
- void RestoreDialogLocation(DialogPtr theDialog,short resID)
- {
- // restores the dialog to its saved location
- if (gWindowSaver)
- gWindowSaver->RestoreWindow(theDialog,resID + kDialogLocationIDBase);
- }
- #endif
-
- void OffsetDialogItem(DialogPtr theDialog,short theItem,short hOffset,short vOffset)
- {
- // moves the dialog item by the given amount, and redraws the item.
-
- short itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if (theItem == ok)
- InsetRect(&itemBox,-4,-4);
- else
- InsetRect(&itemBox,-1,-1);
- EraseRect(&itemBox);
- if (theItem == ok)
- InsetRect(&itemBox,4,4);
- else
- InsetRect(&itemBox,1,1);
- OffsetRect(&itemBox,hOffset,vOffset);
- SetDItem(theDialog,theItem,itemType,itemHand,&itemBox);
-
- // if the dialog item is a control, it is necessary to offset the control rect also
-
- if (itemType & ctrlItem)
- (*(ControlHandle) itemHand)->contrlRect = itemBox;
-
- DrawDialogItem(theDialog,theItem);
- SetPort(savePort);
- }
-
-
- PopUpInfoHdl GetDialogPopUpMenuInfo(DialogPtr theDialog,short theItem)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
-
- if (((itemType & 0x7F) == (ctrlItem + resCtrl)) && (itemHand != NULL))
- return((PopUpInfoHdl)(*(ControlHandle) itemHand)->contrlData);
- else
- return(NULL);
- }
-
- #ifndef __COLOURLAB__
-
- void PutUpDialog(DialogPtr theDialog)
- {
- // replacement for ShowWindow does the right thing with floaters for activate events
-
- ActivateFloatersAndTopDocument(FALSE);
- ShowWindow(theDialog);
- }
-
-
- void TakeDownDialog(DialogPtr theDialog)
- {
- // replacement for ShowWindow does the right thing with floaters for activate events
-
- HideWindow(theDialog);
- ActivateFloatersAndTopDocument(TRUE);
- }
-
- #endif
-
- void Add3DDialogEffects(DialogPtr theDialog)
- {
- // this routine is called when an update for the dialog occurrs (provided you use the std
- // filter proc provided here), and adds 3D effects to the window, such as recessing any
- // edit fields, etc
-
- short itemCount,index,itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- itemCount = CountDITL(theDialog);
- GetPort(&savePort);
- SetPort(theDialog);
- for (index = 1;index <= itemCount;index++)
- {
- GetDItem(theDialog,index,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText)
- {
- InsetRect(&itemBox,-3,-3);
- Frame3DRect(&itemBox,kRecessedEmbossed);
- }
- }
- SetPort(savePort);
- }
-
-
- void SetFPItem(DialogPtr theDialog,short item,float x,short decPlaces)
- {
- // sets the edit text item to a string of the floating point value passed.
-
- short itemType;
- Handle itemHand;
- Rect itemBox;
- decform format;
- decimal d;
- Str255 ts;
-
- GetDItem(theDialog,item,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText ||
- (itemType & 0x7F) == statText)
- {
- if (isnan(x) || ! isfinite(x))
- {
- ts[0] = 1;
- ts[1] = 0xB0;
-
- SysBeep(1);
- }
- else
- {
- format.style = FIXEDDECIMAL;
- format.digits = decPlaces;
-
- num2dec(&format,x,&d);
- dec2str(&format,&d,(char*) &ts[1]);
- ts[0] = strlen((char*) &ts[1]);
- }
- SetIText(itemHand,ts);
- }
- }
-
-
-
- float GetFPItem(DialogPtr theDialog,short item)
- {
- // returns the floating point value of the string in the edit field item
-
- short itemType,ix,vp;
- Handle itemHand;
- Rect itemBox;
- decimal d;
- Str255 ts;
-
- GetDItem(theDialog,item,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText ||
- (itemType & 0x7F) == statText)
- {
- GetIText(itemHand,ts);
-
- if (ts[1] == 0xB0)
- {
- return (1.0 / 0.0);
- }
- else
- {
- ts[ts[0] + 1] = 0;
- ix = 1;
- str2dec((char*) &ts,&ix,&d,&vp);
-
- if (vp)
- return dec2num(&d);
- }
- }
- return 0;
- }
-
-
- void SetItemValue(DialogPtr theDialog,short theItem,short ctlValue)
- {
- // sets the control item to value, if it is a control
-
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if (itemType & ctrlItem)
- SetCtlValue((ControlHandle) itemHand,ctlValue);
- else
- {
- if (itemType & (statText + editText))
- {
- Str255 iText;
-
- NumToString(ctlValue,iText);
- SetIText(itemHand,iText);
- }
- }
- }
-
-
- short GetItemValue(DialogPtr theDialog, short theItem)
- {
- // gets the value of the control item , if it is a control
-
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if (itemType & ctrlItem)
- return GetCtlValue((ControlHandle) itemHand);
- else
- {
- if (itemType & (statText + editText))
- {
- long number;
- Str255 iText;
-
- GetIText(itemHand,iText);
- StringToNum(iText,&number);
-
- return LoWord(number);
- }
- else
- return -1;
- }
- }
-
-
- void HiliteCtlItem(DialogPtr theDialog,short theItem,short hState)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
- if (itemType & ctrlItem)
- HiliteControl((ControlHandle) itemHand,hState);
- }
-
-
- void DrawCTabInRect(Rect* aRect,CTabHandle aCTab)
- {
- // draws the colour table in the rect as best it can. This is useful for previewing palettes,
- // etc. Draws in the current port using RGBForeColor to set the colours.
-
- short numColours,index,rows,cols,i;
- Rect pr,osRect;
- PicHandle aPic;
-
-
- if (aCTab)
- {
- SetRect(&pr,0,0,8,8);
- numColours = (*aCTab)->ctSize + 1;
- /*
- rows = numColours / 8;
- (rows < 1)? cols = numColours : cols = 8;
- */
- cols = numColours;
- rows = 1;
- SetRect(&osRect,0,0,8 * cols,8 * rows);
-
- aPic = OpenPicture(&osRect);
- index = 0;
- while(rows--)
- {
- for(i = 0;i < cols;i++)
- {
- RGBForeColor(&(*aCTab)->ctTable[index++].rgb);
- PaintRect(&pr);
- OffsetRect(&pr,8,0);
- }
- OffsetRect(&pr,-cols * 8,8);
- }
- ClosePicture();
- DrawPicture(aPic,aRect);
- KillPicture(aPic);
- }
- }
-
-
- void SetDialogFontStyle(DialogPtr theDialog,short fontID,short fontSize)
- {
- // this changes the dialog's font and size for static and edit text items. This works by
- // changing the port and TE record parameters directly. It does not change any globals
- // (unlike SetDAFont) so is in force for the duration of this dialog only. Much more
- // useful than anything apple ever provided. Hmmm.
-
- DialogPeek dp;
- TEHandle teH;
- GrafPtr savePort;
- short saveSelStart,saveSelEnd;
-
- if (theDialog)
- {
- GetPort(&savePort);
- SetPort(theDialog);
-
- TextFont(fontID);
- TextSize(fontSize);
- TextFace(0);
-
- dp = (DialogPeek) theDialog;
- teH = dp->textH;
-
- if (teH)
- {
- TEDeactivate(teH);
- saveSelStart = (*teH)->selStart;
- saveSelEnd = (*teH)->selEnd;
- // see if this is a styled text edit record. It is if the size field is negative.
-
- if ((*teH)->txSize < 0)
- {
- // changing the styles for a styled record is trickier- we need to select the
- // text and change the styles using the API, because otherwise things get
- // horrendous.
-
- TextStyle tStyleInfo;
- RGBColor black = {0,0,0};
-
- tStyleInfo.tsFont = fontID;
- tStyleInfo.tsFace = 0;
- tStyleInfo.tsSize = fontSize;
- tStyleInfo.tsColor = black;
-
- TESetSelect(0,32767,teH);
- TESetStyle(doFont + doSize,&tStyleInfo,FALSE,teH);
- }
- else
- {
- // old-style record, so set fields directly
-
- (*teH)->txSize = fontSize;
- (*teH)->txFont = fontID;
-
- // set the lineheight and font ascent
-
- FontInfo fi;
-
- GetFontInfo(&fi);
-
- (*teH)->lineHeight = fi.ascent + fi.descent + fi.leading;
- (*teH)->fontAscent = fi.ascent;
- }
- TECalText(teH);
- TESetSelect(saveSelStart,saveSelEnd,teH);
- TEActivate(teH);
- }
- SetPort(savePort);
-
- if (((WindowPeek)theDialog)->visible)
- DrawDialog(theDialog);
- }
- }
-
-
-
- void Scale2Rects(Rect *theRect,Rect *refRect)
- {
- // this function resizes <theRect> so that it will fit into <refRect>, but preserving its
- // original aspect ratio. This is useful for preventing unwanted stretching of pictures
- // both for creation and display of preview images. Note this also centres the rect within
- // the refRect for the shorter dimension. This is the more intuitively correct behaviour
-
- Fixed aspectRatio;
- Rect destFrame;
- short refWidth,refHeight;
-
- destFrame.top = destFrame.left = 0;
- OffsetRect(theRect,-theRect->left,-theRect->top);
-
- refWidth = refRect->right - refRect->left;
- refHeight = refRect->bottom - refRect->top;
-
- if (theRect->right < theRect->bottom)
- {
- // the rect is taller than it is wide, so we centre horizontally
-
- aspectRatio = FixRatio(theRect->right,theRect->bottom);
- destFrame.right = FixRound(FixMul(aspectRatio,FixRatio(refHeight,1)));
- destFrame.bottom = refHeight;
-
- OffsetRect(&destFrame,refRect->left + ((refWidth - destFrame.right) / 2),refRect->top);
- }
- else
- {
- // the rect is wider than it is tall, so we centre vertically
-
- aspectRatio = FixRatio(theRect->bottom,theRect->right);
- destFrame.bottom = FixRound(FixMul(aspectRatio,FixRatio(refWidth,1)));
- destFrame.right = refWidth;
-
- OffsetRect(&destFrame,refRect->left,refRect->top + ((refHeight - destFrame.bottom) / 2));
- }
- *theRect = destFrame;
- }
-
-
- void ConvertStatToEdit(DialogPtr theDialog,short theItem)
- {
- // changes the static text item with the item number passed to an editable field.
- short itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
- DialogPeek dp;
-
- dp = (DialogPeek) theDialog;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == statText)
- {
- itemType = editText | (itemType & itemDisable);
-
- SetDItem(theDialog,theItem,itemType,itemHand,&itemBox);
-
- if (dp->editField < 0)
- {
- // editing is currently not enabled for this dialog, so enable it
- // by making this field the focus of the editing.
-
- SelIText(theDialog,theItem,0,32767);
- }
-
- GetPort(&savePort);
- SetPort(theDialog);
- InsetRect(&itemBox,-4,-4);
- InvalRect(&itemBox);
- SetPort(savePort);
- }
- }
-
-
-
- void ConvertEditToStat(DialogPtr theDialog,short theItem)
- {
- // changes the edit text item passed to a static text item. If this is the current edit item
- // the text record is deactivated and the tab index changed.
-
- short itemType,iCount,i;
- Handle itemHand;
- Rect itemBox,iBox;
- GrafPtr savePort;
- DialogPeek dp;
-
- dp = (DialogPeek) theDialog;
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText)
- {
- itemType = statText | (itemType & itemDisable);
-
- SetDItem(theDialog,theItem,itemType,itemHand,&itemBox);
-
- if ((dp->editField + 1) == theItem)
- {
- // this is the current edit field, which is a bad thing. We need to make some
- // other field the current one, as this one is no longer editable. To do this,
- // we need to look for another edit item that can assume the focus.
-
- iCount = CountDITL(theDialog);
-
- for (i = 1;i < iCount;i++)
- {
- GetDItem(theDialog,i,&itemType,&itemHand,&iBox);
- if ((itemType & 0x7F) == editText)
- {
- // found one, so switch the focus to that field
-
- SelIText(theDialog,i,0,32767);
- break;
- }
- }
-
- if (i >= iCount)
- {
- // no further fields found, so instead we have to "switch off" editing in this
- // dialog altogether. WARNING: This uses an undocumented feature of the dialog
- // manager!
-
- TESetSelect(0,0,dp->textH);
- dp->editField = -1;
- }
- }
- GetPort(&savePort);
- SetPort(theDialog);
- InsetRect(&itemBox,-4,-4);
- EraseRect(&itemBox);
- InvalRect(&itemBox);
- SetPort(savePort);
- }
- }
-
-
-
- void NewFieldInfo()
- {
- if (gFieldInfo)
- DisposeHandle(gFieldInfo);
-
- gFieldInfo = NewHandle(0); // handle grows as records added
- }
-
-
- void SetEditFieldType(DialogPtr theDialog, short theItem, short theType)
- {
- // registers the dialog item, which must be an edit field (other items are ignored) so that
- // the standard filter proc knows what characters it can allow typed there.
-
- Handle itemHand;
- short itemType;
- Rect itemBox;
- fieldInfo fi;
- short numFields;
-
- if (gFieldInfo == NULL)
- NewFieldInfo();
-
- GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText)
- {
- long gfiSize = GetHandleSize(gFieldInfo);
-
- numFields = gfiSize / sizeof(fieldInfo);
-
- SetHandleSize(gFieldInfo,gfiSize + sizeof(fieldInfo));
-
-
- fi.fieldID = theItem;
- fi.fieldType = theType;
-
- (* (fieldInfo**) gFieldInfo)[numFields] = fi;
- }
- }
-
-
-
- void DisposeFieldInfo()
- {
- if (gFieldInfo)
- DisposeHandle(gFieldInfo);
-
- gFieldInfo = NULL;
- }
-
-
- Boolean PassCharToField(DialogPeek theDialog, unsigned char theChar)
- {
- // passes the character to the current text field, provided that the char
- // is permitted by the current field type. Return indicated whether character is typeable,
- // NOT whether it was legal. This is generally more useful when employing this call in
- // dialog filters (its intended use!)
-
- Boolean legalChar,typeableChar;
-
- // take a quick exit if a) the dialog has no textEdit record, or b) it has no edit fields.
-
- if ((theDialog->textH == NULL) ||
- ! HasEditFields((DialogPtr) theDialog))
- return FALSE;
-
- typeableChar = (theChar >= 0x20 && theChar <= 0x7E) ||
- (theChar >= 0x80 && theChar <= 0xFF);
-
- if (typeableChar)
- {
- short theField = theDialog->editField + 1;
- short rType = GetFieldType(theField);
-
- switch (rType)
- {
- default:
- case kAlphaNumericField:
- legalChar = TRUE;
- break;
- case kIntegerField:
- legalChar = (theChar >= '0' && theChar <= '9');
- break;
- case kFloatingPointField:
- legalChar = (theChar >= '0' && theChar <= '9') || (theChar == '.') || (theChar == '-');
- break;
- case kAlphaOnlyField:
- legalChar = (theChar >= 'a' && theChar <= 'z') ||
- (theChar >= 'A' && theChar <= 'Z');
-
- break;
- case kSignedIntegerField:
- legalChar = (theChar >= '0' && theChar <= '9') || (theChar == '-');
- break;
- case kUnsignedFloatingField:
- legalChar = (theChar >= '0' && theChar <= '9') || (theChar == '.');
- break;
- }
-
- if (legalChar)
- TEKey(theChar,theDialog->textH);
- else
- SysBeep(1);
- }
-
- return typeableChar;
- }
-
-
- static short GetFieldType(short theField)
- {
- // searches for the field in the field list. If found, it returns its type. If not found,
- // it returns <kAlphaNumericField>
-
- fieldInfo fi;
- long numFields;
- short rType = kAlphaNumericField;
-
- if (gFieldInfo == NULL)
- return kAlphaNumericField;
-
- numFields = GetHandleSize(gFieldInfo) / sizeof(fieldInfo);
-
- while(numFields--)
- {
- fi = (* (fieldInfo**) gFieldInfo)[numFields];
-
- if (fi.fieldID == theField)
- {
- rType = fi.fieldType;
- break;
- }
- }
-
- return rType;
- }
-
-
- Boolean HasEditFields(DialogPtr theDialog)
- {
- short i,itemType;
- Handle itemHand;
- Rect itemBox;
- Boolean hasAField = FALSE;
-
- i = CountDITL(theDialog);
-
- while(i)
- {
- GetDItem(theDialog,i--,&itemType,&itemHand,&itemBox);
-
- if ((itemType & 0x7F) == editText)
- {
- hasAField = TRUE;
- break;
- }
- }
-
- return hasAField;
- }
-
-
- static short GetItemFlags(DialogPtr theDialog, short theItem);
- static void SetItemFlags(DialogPtr theDialog, short theItem, short flags);
- static void AddDialogRef(DialogPtr theDialog, short theItem);
- static void RemoveDialogRefs(DialogPtr theDialog);
-
-
- static short GetItemFlags(DialogPtr theDialog, short theItem)
- {
- // find the first occurrence of dialog and item in the list and return the associated
- // flags.
-
- short flags = 0x8000;
- short numEntries;
- itemInfo info;
-
- if (gExtraDialogInfo)
- {
- numEntries = GetHandleSize((Handle) gExtraDialogInfo) / sizeof(itemInfo);
-
- while (numEntries)
- {
- info = (*gExtraDialogInfo)[--numEntries];
-
- if (info.theDlg == theDialog &&
- info.itemID == theItem)
- {
- flags = info.flags;
- break;
- }
- }
- }
-
- return flags;
- }
-
-
- static void SetItemFlags(DialogPtr theDialog, short theItem, short flags)
- {
- short numEntries;
- itemInfo info;
-
- if (gExtraDialogInfo)
- {
- numEntries = GetHandleSize((Handle) gExtraDialogInfo) / sizeof(itemInfo);
-
- while (numEntries)
- {
- info = (*gExtraDialogInfo)[--numEntries];
-
- if (info.theDlg == theDialog &&
- info.itemID == theItem)
- {
- info.flags = flags;
- (*gExtraDialogInfo)[numEntries] = info;
- break;
- }
- }
- }
- }
-
-
- static void AddDialogRef(DialogPtr theDialog, short theItem)
- {
- // extends the handle to include a new entry and sets the entry to this item and
- // dialog. The flags are initialised to 0. Duplicates are not checked for- the caller
- // generally should.
-
- short numEntries;
- itemInfo info;
-
- if (gExtraDialogInfo)
- {
- numEntries = GetHandleSize((Handle) gExtraDialogInfo) / sizeof(itemInfo);
-
- SetHandleSize((Handle) gExtraDialogInfo, (numEntries + 1) * sizeof(itemInfo));
-
- if (! MemError())
- {
- info.theDlg = theDialog;
- info.itemID = theItem;
- info.flags = 0;
-
- (*gExtraDialogInfo)[numEntries] = info;
- }
- }
- }
-
-
- static void RemoveDialogRefs(DialogPtr theDialog)
- {
- // removes all entries from the register that pertain to this dialog. This shortens the
- // handle by one entry as each is found and moves the others up to fill any gaps. This
- // is normally done as part of the clean-up for the dialog. If the handle is emptied by
- // this operation, the caller should dispose it.
-
- short numEntries,i,endCount;
- itemInfo info;
-
- if (gExtraDialogInfo)
- {
- endCount = numEntries = GetHandleSize((Handle) gExtraDialogInfo) / sizeof(itemInfo);
- endCount--;
-
- // work from the bottom up, thus simplifying the closing of
- // gaps if needed.
-
- while(numEntries)
- {
- info = (*gExtraDialogInfo)[--numEntries];
-
- if (info.theDlg == theDialog)
- {
- // this is one to snuff out, so first move up the items
- // below this one...
-
- for (i = numEntries + 1; i < endCount; i++)
- (*gExtraDialogInfo)[i] = (*gExtraDialogInfo)[i + 1];
-
- // ...now shorten the handle
-
- SetHandleSize((Handle) gExtraDialogInfo, endCount * sizeof(itemInfo));
- endCount--;
- }
- }
- }
- }
-
-
- void InitFunkyDialog(DialogPtr theDialog)
- {
- if (gExtraDialogInfo == NULL)
- gExtraDialogInfo = (itemInfo**) NewHandle(0);
- }
-
-
- void DisposeFunkyDialog(DialogPtr theDialog)
- {
- if (gExtraDialogInfo)
- {
- RemoveDialogRefs(theDialog);
-
- if (GetHandleSize((Handle) gExtraDialogInfo) == 0)
- {
- DisposeHandle((Handle) gExtraDialogInfo);
- gExtraDialogInfo = NULL;
- }
- }
- }
-
-
- void GreyOutItem(DialogPtr theDialog, short theItem)
- {
- // this marks the given item as greyed out, and posts an update for it. The standard
- // filter will pick this up and grey out the item. For edit text items, the item is
- // converted to static text and the border refreshed.
-
- short itemType,flags;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- if (gExtraDialogInfo)
- {
- GetDItem(theDialog, theItem, &itemType, &itemHand, &itemBox);
-
- if (itemType & ctrlItem)
- HiliteCtlItem(theDialog, theItem, 255);
- else
- {
- // is the item registered with us?
-
- flags = GetItemFlags(theDialog, theItem);
- if (flags < 0)
- {
- AddDialogRef(theDialog, theItem);
- flags = 0;
- }
-
- // if an edit text item, convert to static
-
-
- if ((itemType & 0x7F) == editText)
- {
- ConvertEditToStat(theDialog, theItem);
- InsetRect(&itemBox, -4, -4);
-
- flags |= kWasEditTextItem;
- }
-
- // flag the item as greyed out
-
- flags |= kGreyedOut;
- SetItemFlags(theDialog, theItem, flags);
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- InvalRect(&itemBox);
- SetPort(savePort);
- }
- }
- }
-
-
- void UngreyOutItem(DialogPtr theDialog, short theItem)
- {
- short itemType,flags;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- if (gExtraDialogInfo)
- {
- GetDItem(theDialog, theItem, &itemType, &itemHand, &itemBox);
-
- if (itemType & ctrlItem)
- HiliteCtlItem(theDialog, theItem, 0);
- else
- {
- // is the item registered with us?
-
- flags = GetItemFlags(theDialog, theItem);
- if (flags < 0)
- return; // never heard of it, guv.
-
- // if was previously an edit text item, convert back to edit
-
- if (((itemType & 0x7F) == statText) && (flags & kWasEditTextItem))
- {
- ConvertStatToEdit(theDialog, theItem);
- InsetRect(&itemBox, -4, -4);
-
- flags &= ~kWasEditTextItem;
- }
-
- // flag the item as no longer greyed out
-
- flags &= ~kGreyedOut;
- SetItemFlags(theDialog, theItem, flags);
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- InvalRect(&itemBox);
- SetPort(savePort);
- }
- }
- }
-
-
- void DrawGreyItem(DialogPtr theDialog, short theItem)
- {
- short itemType,flags;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
- Pattern grayPat = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- GetDItem(theDialog, theItem, &itemType, &itemHand, &itemBox);
- flags = GetItemFlags(theDialog, theItem);
-
- PenNormal();
-
- // if this was previously an edit text item, draw a border before greying it out
-
- if (((itemType & 0x7F) == statText) && (flags & kWasEditTextItem))
- {
- InsetRect(&itemBox, -3, -3);
- FrameRect(&itemBox);
- }
-
- PenMode(srcBic);
- PenPat(&grayPat);
- PaintRect(&itemBox);
- PenNormal();
-
- SetPort(savePort);
- }
-
-
-
- void UpdateGreyedItems(DialogPtr theDialog)
- {
- // draws the greyed out items by calling DrawGreyItem for each one so marked in the
- // registry. Call AFTER drawing the dialog items in an update.
-
- short numEntries, i;
- itemInfo info;
-
- if (gExtraDialogInfo)
- {
- numEntries = GetHandleSize((Handle) gExtraDialogInfo) / sizeof(itemInfo);
-
- for (i = 0; i < numEntries; i++)
- {
- info = (*gExtraDialogInfo)[i];
-
- if ((info.theDlg == theDialog) && (info.flags & kGreyedOut))
- DrawGreyItem(theDialog, info.itemID);
- }
- }
- }
-
-
- void ZoomToDialog(DialogPtr theDialog, Rect* fromRect)
- {
- // draws a zoom open effect. Requires drag manager.
-
- generalPrefHdl gpH;
- Boolean zoom = TRUE;
-
- gpH = (generalPrefHdl) GetPrefResource('GENP',128);
-
- if (gpH)
- {
- zoom = (*gpH)->zoomFX;
- DisposeHandle((Handle) gpH);
- }
-
- if (zoom && gImportFlags.hasDragManager)
- {
- // to find out where to zoom to, we need to get the rect of the dialog that
- // is about to come up. However, it is not actually visible at this point,
- // so we can't use FrontWindow(). Thus we need to sneak a skanky look at the
- // windowlist. This is a no-no under Copland, so we use the recommended macro.
-
- WindowPtr tw;
- Rect src, dest;
-
- if (theDialog)
- {
- if (fromRect == NULL)
- src = gDialogZoomRect;
- else
- src = *fromRect;
-
- GetWStructRect(theDialog, &dest);
-
- (void) ZoomRects(&src, &dest, 10, zoomAccelerate);
- }
- }
- }
-
-
- void ZoomFromDialog(DialogPtr theDialog, Rect* toRect)
- {
- // draws a zoom close effect- requires drag manager.
-
- generalPrefHdl gpH;
- Boolean zoom = TRUE;
-
- gpH = (generalPrefHdl) GetPrefResource('GENP',128);
-
- if (gpH)
- {
- zoom = (*gpH)->zoomFX;
- DisposeHandle((Handle) gpH);
- }
-
- if (zoom && gImportFlags.hasDragManager)
- {
- Rect src, dest;
-
- if (theDialog)
- {
- if (toRect == NULL)
- src = gDialogZoomRect;
- else
- src = *toRect;
-
- GetWStructRect(theDialog, &dest);
-
- // make sure it really is a dialog before hiding it
-
- if (((WindowPeek) theDialog)->windowKind == dialogKind)
- HideWindow(theDialog);
-
- //(void) ZoomRects(&dest, &src, 10, zoomDecelerate);
-
- // make a chore to do the work, so updates are processed properly
- // N.B. The chore disposes of itself once it has executed.
-
- CZoomChore* aZChore = TCL_NEW(CZoomChore, (&dest, &src));
- gApplication->AssignIdleChore(aZChore);
- }
- }
- }
-
-
-
- void GetWStructRect(WindowPtr aWindow, Rect* aRect)
- {
- // returns the structure rectangle of a window, whether visible or not.
-
- Rect r;
- Point savedLoc;
- GrafPtr savePort;
-
- if (! ((WindowPeek) aWindow)->visible)
- {
- // window hidden, so struc rgn is not valid. save its location, and then
- // move it offscreen, make it visible, get the rect, then put it all back.
-
- GetPort(&savePort);
- SetPort(aWindow);
-
- // record its position
-
- savedLoc = topLeft(aWindow->portRect);
- LocalToGlobal(&savedLoc);
-
- // move it halfway to infinity
-
- MoveWindow(aWindow, savedLoc.h, 0x4000, FALSE);
- ShowHide(aWindow, TRUE);
-
- r = (*((WindowPeek) aWindow)->strucRgn)->rgnBBox;
-
- // now put it all back
-
- ShowHide(aWindow, FALSE);
- MoveWindow(aWindow, savedLoc.h, savedLoc.v, FALSE);
-
- // compensate for window offset
-
- OffsetRect(&r, 0, savedLoc.v - 0x4000);
- SetPort(savePort);
- }
- else
- r = (*((WindowPeek) aWindow)->strucRgn)->rgnBBox;
-
- *aRect = r;
- }
-
-
-
- void SetZoomSrcToItem(DialogPtr theDialog, short item)
- {
- short itemType;
- Handle itemHand;
- Rect itemBox;
- GrafPtr savePort;
-
- if (theDialog)
- {
- GetDItem(theDialog, item, &itemType, &itemHand, &itemBox);
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- InsetRect(&itemBox, 4, 4 );
-
- LocalToGlobal(&topLeft(itemBox));
- LocalToGlobal(&botRight(itemBox));
-
- gDialogZoomRect = itemBox;
-
- SetPort(savePort);
- }
- }
-
-
-